package com.ruoyi.controller.jpjs.municipal;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.MsgConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.domain.jpjs.common.excellence.Excellence;
import com.ruoyi.domain.jpjs.common.machinery.*;
import com.ruoyi.domain.jpjs.common.mater.Mater;
import com.ruoyi.domain.jpjs.common.mater.MaterCount;
import com.ruoyi.domain.jpjs.common.mater.MaterDay;
import com.ruoyi.domain.jpjs.common.mater.MaterImport;
import com.ruoyi.domain.jpjs.common.municipal.Income;
import com.ruoyi.domain.jpjs.common.municipal.IncomeDetail;
import com.ruoyi.domain.jpjs.common.municipal.IncomeParam;
import com.ruoyi.domain.jpjs.common.municipal.expend.Manage;
import com.ruoyi.domain.jpjs.common.municipal.expend.Team;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.service.jpjs.municipal.ManageService;
import com.ruoyi.system.domain.SysDictSon;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysDictDataService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 市政收入 控制层
 */
@SuppressWarnings("ALL")
@Controller
@RequestMapping("/manage")
public class ManageController extends BaseController {

    private String prefix = "jpjs/municipal/cost";

    @Autowired
    private ManageService manageService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 首页面
     */
    @GetMapping()
    public String view(ModelMap mmp) {
        // Step1 材料费用Tab -> 初始化筛选条件 -> 供应商、出租单位
        mmp.put("supplierNames", sysDictDataService.selectDictDataByType("supplier_name"));
        mmp.put("rentalNames", sysDictDataService.selectDictDataByType("rental_name"));

        return prefix + "/list";
    }

    /**
     * 首页面 -> 初始化数据
     */
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(Manage manage) {
        startPage();
        manage.setProgramName(manage.getProgramName().trim().replaceAll(",", ""));
        manage.setUserId(ShiroUtils.getSysUser().getUserId());
        // 获取当前登录人对应的项目权限
        List<Manage> manages = manageService.queryManageList(manage);
        return getDataTable(manages);
    }

    /**
     * 新增页面
     */
    @GetMapping("/addView")
    public String addView(ModelMap mmp, String programName, String companyId, String programId) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("companyId", companyId);
        mmp.put("programId", programId);
        mmp.put("programName", programName);
        return prefix + "/add";
    }

    /**
     * 新增页面 -> 保存
     */
    @PostMapping("/save")
    @ResponseBody
    public AjaxResult save(Manage manage) {
        // Step1 校验同一个项目下,实际月份唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMonthUnique(manage))) {
            return error("该项目下存在重复月份!");
        }
        return toAjax(manageService.insertManage(manage));
    }

    /**
     * 编辑页面
     */
    @GetMapping("/editView")
    public String editView(ModelMap mmp, String manageId) {
        Map<String, Object> map = new HashMap<>();
        map.put("manageId", manageId);
        Manage manage = new Manage();
        manage.setManageId(Integer.valueOf(manageId));
        // 费用管理信息
        List<Manage> manages = manageService.queryManageList(manage);
        mmp.put("manages", manages.get(0));
        return prefix + "/edit";
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult edit(Manage manage) {
        // Step1 校验同一个项目下,实际月份唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMonthUniqueEdit(manage))) {
            return error("更新费用管理,存在重复月份!");
        }
        return toAjax(manageService.updateManage(manage));
    }

    /**
     * 首页面 -> 批量删除
     */
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids) {
        try {
            return toAjax(manageService.deleteManageById(ids));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(Manage manage) {
        manage.setProgramName(manage.getProgramName().trim().replaceAll(",", ""));
        manage.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Manage> list = manageService.queryManageList(manage);
        ExcelUtil<Manage> util = new ExcelUtil<Manage>(Manage.class);
        return util.exportExcel(list, "费用管理");
    }

    /**
     * 首页面 -> 初始化数据
     */
    @PostMapping("/listTeam")
    @ResponseBody
    public TableDataInfo listTeam(Team team) {
        startPage();
        team.setProgramName(team.getProgramName().trim().replaceAll(",", ""));
        team.setUserId(ShiroUtils.getSysUser().getUserId());
        // 获取当前登录人对应的项目权限
        List<Team> teams = manageService.queryTeamList(team);
        return getDataTable(teams);
    }

    /**
     * 新增页面
     */
    @GetMapping("/addTeamView")
    public String addTeamView(ModelMap mmp, String programName, String companyId, String programId) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("companyId", companyId);
        mmp.put("programId", programId);
        mmp.put("programName", programName);
        mmp.put("teamName", sysDictDataService.selectDictDataByType("team_name"));
        return prefix + "/teamAdd";
    }

    /**
     * 新增页面 -> 保存
     */
    @PostMapping("/saveTeam")
    @ResponseBody
    public AjaxResult saveTeam(Team team) {
        // Todo 是否需要校验
        team.setCreater(ShiroUtils.getSysUser().getUserName());
        return toAjax(manageService.insertTeam(team));
    }

    /**
     * 编辑页面
     */
    @GetMapping("/editTeamView")
    public String editTeamView(ModelMap mmp, String teamId) {
        Map<String, Object> map = new HashMap<>();
        map.put("TeamId", teamId);
        Team team = new Team();
        team.setTeamId(Integer.valueOf(teamId));
        // 费用管理信息
        List<Team> teams = manageService.queryTeamList(team);
        mmp.put("teamName", sysDictDataService.selectDictDataByType("team_name"));
        mmp.put("team", teams.get(0));
        return prefix + "/teamEdit";
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/editTeam")
    @ResponseBody
    public AjaxResult edit(Team team) {
        return toAjax(manageService.updateTeam(team));
    }

    /**
     * 首页面 -> 批量删除
     */
    @PostMapping("/removeTeam")
    @ResponseBody
    public AjaxResult removeTeam(String ids) {
        try {
            return toAjax(manageService.deleteTeamById(ids));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/exportTeam")
    @ResponseBody
    public AjaxResult exportTeam(Team team) {
        team.setProgramName(team.getProgramName().trim().replaceAll(",", ""));
        team.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Team> list = manageService.queryTeamList(team);
        ExcelUtil<Team> util = new ExcelUtil<Team>(Team.class);
        return util.exportExcel(list, "班组分包费用");
    }

    @PostMapping("/listMater")
    @ResponseBody
//    public Map  listMater(Mater mater, @RequestParam Map map) {
    public TableDataInfo listMater(Mater mater) {
//        int pageSize = Integer.parseInt(map.get("pageSize").toString());
//        int pageNum = Integer.parseInt(map.get("pageNum").toString());
        mater.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Mater> resultList = new ArrayList<>();
        List<Mater> materss = manageService.queryMaterList(mater);

        startPage();

        mater.setProgramName(mater.getProgramName().trim().replaceAll(",", ""));
        List<Mater> maters = manageService.queryMaterList(mater);


        // 含税金额
        if (StringUtils.isNotEmpty(maters)) {
            for (Mater materObj : maters) {
                List<Mater> materList = manageService.queryMaterForQuantity(materObj);
                List<Mater> materPreviousList = manageService.queryMaterForPrevious(materObj);

                double unitPriceTax = materObj.getUnitPriceTax() == null ? 0.0 : materObj.getUnitPriceTax();  // 含税单价
                double purchaseQuan = materObj.getPurchaseQuantity() == null ? 0.0 : materObj.getPurchaseQuantity(); // 采购数量
                // 本期含税金额
                double amountIncludingTaxCurrent = getNum(unitPriceTax * purchaseQuan);

                String taxRate = StringUtils.isNotEmpty(String.valueOf(materObj.getTaxRate())) ? materObj.getTaxRate() : "0";

                // 采购数量(累计值)
                if (StringUtils.isNotEmpty(materList)) {
                    double quantity = 0;
                    double amountIncludingTax = 0;
                    double amountIncluding = 0;
                    for (Mater mat : materList) {
                        // 含税单价
                        double unitPriceTaxMonth = mat.getUnitPriceTax() == null ? 0.0 : mat.getUnitPriceTax();

                        // 累加采购数量
                        double purchaseQuantity = mat.getPurchaseQuantity() != null ? mat.getPurchaseQuantity() : 0.0;
                        quantity = quantity + purchaseQuantity;
                        materObj.setPurchaseQuantity(getNum(quantity));

                        // 累加含税金额
                        double amountIncludingTaxMonth = unitPriceTaxMonth * purchaseQuantity;
                        amountIncludingTax = amountIncludingTax + amountIncludingTaxMonth;
                        materObj.setAmountIncludingTax(getNum(amountIncludingTax));

                        // 累加不含税金额
                        double amountIncludingMonth = amountIncludingTaxMonth / (1 + Float.valueOf(taxRate) / 100);
                        amountIncluding = amountIncluding + amountIncludingMonth;
                        materObj.setAmountIncluding(getNum(amountIncluding));
                    }
                } else {
                    materObj.setPurchaseQuantity(0.0);
                    materObj.setAmountIncludingTax(0.0);
                    materObj.setAmountIncluding(0.0);
                }


                double purchaseQuantity = materObj.getPurchaseQuantity() == null ? 0.0 : materObj.getPurchaseQuantity();  // 采购数量
                double currentSurplus = materObj.getCurrentSurplus() == null ? 0.0 : materObj.getCurrentSurplus();    // 本期剩余量
                // 不含税单价 (不含税金额/采购数量)
                double unitPrice = materObj.getAmountIncluding() / purchaseQuantity;
                if (purchaseQuantity == 0) {
                    materObj.setUnitPrice(0.0);
                } else {
                    materObj.setUnitPrice(getNum(unitPrice));
                }
                // 税金 (含税金额-不含税单价)
                materObj.setTaxes(getNum(materObj.getAmountIncludingTax() - materObj.getAmountIncluding()));
                // 本期剩余金额 (含税单价*本期剩余量)
                materObj.setCurrentRemainPrice(getNum(unitPriceTax * currentSurplus));
                // 上期累计消耗量
                // 当前月的上期累计消耗量 = 上个月的累计消耗量 + 上个月的本期消耗量  (之前月份的本期消耗量)
                if (StringUtils.isNotEmpty(materPreviousList)) {
                    double sum = 0; // 本期消耗量初始化
                    double price = 0; // 本期消耗金额初始化

                    for (Mater mat : materPreviousList) {
                        double currentConsump = mat.getCurrentConsump() != null ? mat.getCurrentConsump() : 0.0;
                        double currentConsumptionAmount = mat.getCurrentConsumptionAmount() != null ? mat.getCurrentConsumptionAmount() : 0.0;
                        sum = sum + currentConsump;
                        price = price + currentConsumptionAmount;
                    }

                    materObj.setPreviousTotalConsume(getNum(sum));
                    materObj.setPreviousTotalPrice(getNum(price));
                } else {
                    materObj.setPreviousTotalConsume(0.0);
                    materObj.setPreviousTotalPrice(0.0);
                }
                // 本期消耗量 (采购数量 - 截至上期累计消耗量 - 本期剩余量)
                materObj.setCurrentConsump(getNum(materObj.getPurchaseQuantity() - materObj.getPreviousTotalConsume() - currentSurplus));
                // 本期消耗金额 (含税金额 - 截至上期累计消耗金额 - 本期剩余金额)
//                materObj.setCurrentConsumptionAmount(getNum(amountIncludingTaxCurrent - materObj.getPreviousTotalPrice() - materObj.getCurrentRemainPrice()));
                materObj.setCurrentConsumptionAmount(getNum(materObj.getAmountIncludingTax() - materObj.getPreviousTotalPrice() - materObj.getCurrentRemainPrice()));

                // 累计消耗量 (上期累计消耗量 + 本期消耗量)
                materObj.setCumulativeConsumption(getNum(materObj.getPreviousTotalConsume() + materObj.getCurrentConsump()));
                // 累计消耗金额 (含税金额 - 本期剩余金额)
                materObj.setAccumulatedConsumptionAmount(getNum(materObj.getAmountIncludingTax() - materObj.getCurrentRemainPrice()));

            }
        }


        if (StringUtils.isNotEmpty(materss)) {
            for (Mater materObj : materss) {
                List<Mater> materList = manageService.queryMaterForQuantity(materObj);
                List<Mater> materPreviousList = manageService.queryMaterForPrevious(materObj);

                double unitPriceTax = materObj.getUnitPriceTax() == null ? 0.0 : materObj.getUnitPriceTax();  // 含税单价
                double purchaseQuan = materObj.getPurchaseQuantity() == null ? 0.0 : materObj.getPurchaseQuantity(); // 采购数量
                // 本期含税金额
                double amountIncludingTaxCurrent = getNum(unitPriceTax * purchaseQuan);

                String taxRate = StringUtils.isNotEmpty(String.valueOf(materObj.getTaxRate())) ? materObj.getTaxRate() : "0";

                // 采购数量(累计值)
                if (StringUtils.isNotEmpty(materList)) {
                    double quantity = 0;
                    double amountIncludingTax = 0;
                    double amountIncluding = 0;
                    for (Mater mat : materList) {
                        // 含税单价
                        double unitPriceTaxMonth = mat.getUnitPriceTax() == null ? 0.0 : mat.getUnitPriceTax();

                        // 累加采购数量
                        double purchaseQuantity = mat.getPurchaseQuantity() != null ? mat.getPurchaseQuantity() : 0.0;
                        quantity = quantity + purchaseQuantity;
                        materObj.setPurchaseQuantity(quantity);

                        // 累加含税金额
                        double amountIncludingTaxMonth = unitPriceTaxMonth * purchaseQuantity;
                        amountIncludingTax = amountIncludingTax + amountIncludingTaxMonth;
                        materObj.setAmountIncludingTax(getNum(amountIncludingTax));

                        // 累加不含税金额
                        double amountIncludingMonth = amountIncludingTaxMonth / (1 + Float.valueOf(taxRate) / 100);
                        amountIncluding = amountIncluding + amountIncludingMonth;
                        materObj.setAmountIncluding(getNum(amountIncluding));
                    }
                } else {
                    materObj.setPurchaseQuantity(0.0);
                    materObj.setAmountIncludingTax(0.0);
                    materObj.setAmountIncluding(0.0);
                }


                double purchaseQuantity = materObj.getPurchaseQuantity() == null ? 0.0 : materObj.getPurchaseQuantity();  // 采购数量
                double currentSurplus = materObj.getCurrentSurplus() == null ? 0.0 : materObj.getCurrentSurplus();    // 本期剩余量
                // 不含税单价 (不含税金额/采购数量)
                double unitPrice = materObj.getAmountIncluding() / purchaseQuantity;
                if (purchaseQuantity == 0) {
                    materObj.setUnitPrice(0.0);
                } else {
                    materObj.setUnitPrice(getNum(unitPrice));
                }
                // 税金 (含税金额-不含税单价)
                materObj.setTaxes(getNum(materObj.getAmountIncludingTax() - materObj.getAmountIncluding()));
                // 本期剩余金额 (含税单价*本期剩余量)
                materObj.setCurrentRemainPrice(getNum(unitPriceTax * currentSurplus));
                // 上期累计消耗量
                // 当前月的上期累计消耗量 = 上个月的累计消耗量 + 上个月的本期消耗量  (之前月份的本期消耗量)
                if (StringUtils.isNotEmpty(materPreviousList)) {
                    double sum = 0; // 本期消耗量初始化
                    double price = 0; // 本期消耗金额初始化

                    for (Mater mat : materPreviousList) {
                        double currentConsump = mat.getCurrentConsump() != null ? mat.getCurrentConsump() : 0.0;
                        double currentConsumptionAmount = mat.getCurrentConsumptionAmount() != null ? mat.getCurrentConsumptionAmount() : 0.0;
                        sum = sum + currentConsump;
                        price = price + currentConsumptionAmount;
                    }

                    materObj.setPreviousTotalConsume(getNum(sum));
                    materObj.setPreviousTotalPrice(getNum(price));
                } else {
                    materObj.setPreviousTotalConsume(0.0);
                    materObj.setPreviousTotalPrice(0.0);
                }
                // 本期消耗量 (采购数量 - 截至上期累计消耗量 - 本期剩余量)
                // 本期剩余量  没有值
                materObj.setCurrentConsump(getNum(materObj.getPurchaseQuantity() - materObj.getPreviousTotalConsume() - currentSurplus));
                // 本期消耗金额 (含税金额 - 截至上期累计消耗金额 - 本期剩余金额)
//                materObj.setCurrentConsumptionAmount(getNum(amountIncludingTaxCurrent - materObj.getPreviousTotalPrice() - materObj.getCurrentRemainPrice()));
                materObj.setCurrentConsumptionAmount(getNum(materObj.getAmountIncludingTax() - materObj.getPreviousTotalPrice() - materObj.getCurrentRemainPrice()));

                // 累计消耗量 (上期累计消耗量 + 本期消耗量)
                materObj.setCumulativeConsumption(getNum(materObj.getPreviousTotalConsume() + materObj.getCurrentConsump()));
                // 累计消耗金额 (含税金额 - 本期剩余金额)
                materObj.setAccumulatedConsumptionAmount(getNum(materObj.getAmountIncludingTax() - materObj.getCurrentRemainPrice()));

            }
        }


        manageService.deleteMaterCount();
        // 按照不同项目不同月份统计求和
        for (Mater materObj : materss) {
            MaterCount materCount = new MaterCount();
            materCount.setProgramId(materObj.getProgramId());
            materCount.setActualMonth(materObj.getActualMonth());
            materCount.setCurrentConsumptionAmount(materObj.getCurrentConsumptionAmount());
            manageService.insertMaterCount(materCount);
        }

//        int currIdx = (pageNum > 1 ? (pageNum - 1) * pageSize : 0);
//        for (int i = 0; i < pageSize && i < maters.size() - currIdx; i++) {
//            Mater materObj = maters.get(currIdx + i);
//            resultList.add(materObj);
//        }

//        Map map2 = new HashMap();
//        map2.put("list", resultList);
//        map2.put("total", resultList.size());

        return getDataTable(maters);
    }

    /**
     * 新增页面
     */
    @GetMapping("/addMaterView")
    public String addMaterView(ModelMap mmp, String programName, String companyId, String programId) {
        Map<String, Object> map = new HashMap<>();

        mmp.put("unitNames", sysDictDataService.selectDictDataByType("unit_name"));
        mmp.put("supplierNames", sysDictDataService.selectDictDataByType("supplier_name"));
        mmp.put("companyId", companyId);
        mmp.put("programId", programId);
        mmp.put("programName", programName);
        return prefix + "/materAdd";
    }

    /**
     * 新增、编辑页面 根据楼栋号获取楼层号
     */
    @GetMapping("/selectMaterNameByCode")
    @ResponseBody
    public Map selectMaterNameByCode(SysDictSon sysDictSon) {
        Map<String, Object> map = new HashMap<>();
        List<SysDictSon> materNames = sysDictDataService.selectDictSonByCode(sysDictSon);
        map.put("materNames", materNames);
        return map;
    }

    @PostMapping("/checKIfFirst")
    @ResponseBody
    public String checKIfFirst(Mater mater) {
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMaterUnique(mater))) {
            // 不是首次添加(物料的唯一性),无需展示本期消耗量
            return "1";
        } else {
            // 首次添加,需展示本期消耗量
            return "0";
        }
    }

    /**
     * 新增页面 -> 保存
     */
    @PostMapping("/saveMater")
    @ResponseBody
    public AjaxResult saveMater(Mater mater) {
        // Step1 校验同一个项目下,供应商、物料名称、规格型号的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMaterUniqueAdd(mater))) {
            return error("存在重复月份或物料！");
        }
        return toAjax(manageService.addMater(mater));
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/exportMater")
    @ResponseBody
    public AjaxResult exportMater(Mater mater) {
        mater.setProgramName(mater.getProgramName().trim().replaceAll(",", ""));
        mater.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Mater> maters = manageService.queryMaterList(mater);

        // 含税金额
        if (StringUtils.isNotEmpty(maters)) {
            for (Mater materObj : maters) {
                List<Mater> materList = manageService.queryMaterForQuantity(materObj);
                List<Mater> materPreviousList = manageService.queryMaterForPrevious(materObj);

                // 采购数量
                if (StringUtils.isNotEmpty(materList)) {
                    double quantity = 0;
                    for (Mater mat : materList) {
                        double purchaseQuantity = mat.getPurchaseQuantity() != null ? mat.getPurchaseQuantity() : 0.0;
                        quantity = quantity + purchaseQuantity;
                        materObj.setPurchaseQuantity(quantity);
                    }
                } else {
                    materObj.setPurchaseQuantity(0.0);
                }

                double unitPriceTax = materObj.getUnitPriceTax() == null ? 0.0 : materObj.getUnitPriceTax();  // 含税单价
                double purchaseQuantity = materObj.getPurchaseQuantity() == null ? 0.0 : materObj.getPurchaseQuantity();  // 采购数量
                double currentSurplus = materObj.getCurrentSurplus() == null ? 0.0 : materObj.getCurrentSurplus();    // 本期剩余量
                String taxRate = StringUtils.isNotEmpty(String.valueOf(materObj.getTaxRate())) ? materObj.getTaxRate() : "0";
                // 含税金额 (含税单价*采购数量)
                materObj.setAmountIncludingTax(getNum(unitPriceTax * purchaseQuantity));
                // 不含税金额 (含税金额/(1+税率))
                double amountIncludingTax = materObj.getAmountIncludingTax() / (1 + Float.valueOf(taxRate) / 100);
                materObj.setAmountIncluding(getNum(amountIncludingTax));
                // 不含税单价 (不含税金额/采购数量)
                double unitPrice = materObj.getAmountIncluding() / purchaseQuantity;
                if (purchaseQuantity == 0) {
                    materObj.setUnitPrice(0.0);
                } else {
                    materObj.setUnitPrice(getNum(unitPrice));
                }
                // 税金 (含税金额-不含税单价)
                materObj.setTaxes(getNum(materObj.getAmountIncludingTax() - materObj.getAmountIncluding()));
                // 本期剩余金额 (含税单价*本期剩余量)
                materObj.setCurrentRemainPrice(getNum(unitPriceTax * currentSurplus));
                // 上期累计消耗量
                // 当前月的上期累计消耗量 = 上个月的累计消耗量 + 上个月的本期消耗量  (之前月份的本期消耗量)
                if (StringUtils.isNotEmpty(materPreviousList)) {
                    double sum = 0; // 本期消耗量初始化
                    double price = 0; // 本期消耗金额初始化

                    for (Mater mat : materPreviousList) {
                        double currentConsump = mat.getCurrentConsump() != null ? mat.getCurrentConsump() : 0.0;
                        double currentConsumptionAmount = mat.getCurrentConsumptionAmount() != null ? mat.getCurrentConsumptionAmount() : 0.0;
                        sum = sum + currentConsump;
                        price = price + currentConsumptionAmount;
                    }

                    materObj.setPreviousTotalConsume(getNum(sum));
                    materObj.setPreviousTotalPrice(getNum(price));
                } else {
                    materObj.setPreviousTotalConsume(0.0);
                    materObj.setPreviousTotalPrice(0.0);
                }
                // 本期消耗量 (采购数量 - 截至上期累计消耗量 - 本期剩余量)
                materObj.setCurrentConsump(getNum(materObj.getPurchaseQuantity() - materObj.getPreviousTotalConsume() - currentSurplus));
                // 本期消耗金额 (含税金额 - 截至上期累计消耗金额 - 本期剩余金额)
                materObj.setCurrentConsumptionAmount(getNum(materObj.getAmountIncludingTax() - materObj.getPreviousTotalPrice() - materObj.getCurrentRemainPrice()));
                // 累计消耗量 (上期累计消耗量 + 本期消耗量)
                materObj.setCumulativeConsumption(getNum(materObj.getPreviousTotalConsume() + materObj.getCurrentConsump()));
                // 累计消耗金额 (含税金额 - 本期剩余金额)
                materObj.setAccumulatedConsumptionAmount(getNum(materObj.getAmountIncludingTax() - materObj.getCurrentRemainPrice()));

            }
        }
        ExcelUtil<Mater> util = new ExcelUtil<Mater>(Mater.class);
        return util.exportExcel(maters, "材料费用");
    }


    /**
     * 编辑页面
     */
    @GetMapping("/editMaterView")
    public String editMaterView(ModelMap mmp, String materialId, String actualMonth) {
        Map<String, Object> map = new HashMap<>();
        map.put("MaterialId", materialId);
        Mater mater = new Mater();
        mater.setMaterialId(Integer.valueOf(materialId));

        String month = null;
        // 费用管理信息
        List<Mater> maters = manageService.queryMaterList(mater);
        // Step2 根据月份判断是否是首次添加记录
        List<Mater> monthMaters = manageService.queryMonthList(maters.get(0));
        if (StringUtils.isNotEmpty(monthMaters)) {
            month = monthMaters.get(0).getActualMonth();
        }
        if (actualMonth.equals(month)) {
            // 首次添加
            mmp.put("showFlag", 1);
        } else {
            // 非首次添加
            mmp.put("showFlag", 2);
        }

        SysDictSon sysDictSon = new SysDictSon();
        sysDictSon.setId(maters.get(0).getMaterId());
        sysDictSon.setDictCode(maters.get(0).getSupplierId());
        List<SysDictSon> sysDictSons = sysDictDataService.selectDictSonById(sysDictSon);
        List<SysDictSon> materNames = sysDictDataService.selectDictSonByCode(sysDictSon);

        mmp.put("materId", sysDictSons.get(0).getId());
        mmp.put("materNames", materNames);


        mmp.put("unitNames", sysDictDataService.selectDictDataByType("unit_name"));
        mmp.put("supplierNames", sysDictDataService.selectDictDataByType("supplier_name"));
        mmp.put("mater", maters.get(0));
        return prefix + "/materEdit";
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/editMater")
    @ResponseBody
    public AjaxResult editMater(Mater mater) {
        // Step1 校验同一个项目下, 供应商、月份、物料名称、规格型号的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMaterUniqueEdit(mater))) {
            return error("存在重复月份或物料！");
        }
        // 首条记录 -> 编辑
        if (mater.getShowFlag().equals("1")) {
            // 本期消耗量 (采购数量 - 上期累计消耗量 - 本期剩余量)
            Mater materObj = manageService.queryMaterList(mater).get(0);
            double purchaseQuantity = materObj.getPurchaseQuantity() != null ? materObj.getPurchaseQuantity() : 0.0;
            double previousTotalConsume = materObj.getPreviousTotalConsume() != null ? materObj.getPreviousTotalConsume() : 0.0;
            double previousTotalPrice = materObj.getPreviousTotalPrice() != null ? materObj.getPreviousTotalPrice() : 0.0;
            mater.setCurrentConsump(getNum(purchaseQuantity - previousTotalConsume - mater.getCurrentSurplus()));

            // 本期消耗金额 (含税金额(含税单价*采购数量) - 上期累计消金额 - 本期剩余金额(含税单价*本期剩余量))
            // 本期剩余金额
            double currentRemainPrice = getNum(mater.getUnitPriceTax() * mater.getCurrentSurplus()) != null ? getNum(mater.getUnitPriceTax() * mater.getCurrentSurplus()) : 0.0;
            // 含税金额(含税单价*采购数量)
            double amountIncludingTax = getNum(purchaseQuantity * mater.getUnitPriceTax());
            mater.setCurrentConsumptionAmount(getNum(amountIncludingTax - previousTotalPrice - currentRemainPrice));


        } else {
            // 本期消耗量 (采购数量 - 上期累计消耗量 - 本期剩余量)
            // 采购数量
            List<Mater> materList = manageService.queryMaterForQuantity(mater);
            double quantity = 0;
            for (Mater mat : materList) {
                double purchaseQuantity = mat.getPurchaseQuantity() != null ? mat.getPurchaseQuantity() : 0.0;
                quantity = quantity + purchaseQuantity;
            }
            // 上期累计消耗量
            List<Mater> materPreviousList = manageService.queryMaterForPrevious(mater);
            double previousTotalConsume = 0; // 本期消耗量初始化
            double price = 0; // 本期消耗金额初始化

            for (Mater mat : materPreviousList) {
                double currentConsump = mat.getCurrentConsump() != null ? mat.getCurrentConsump() : 0.0;
                double currentConsumptionAmount = mat.getCurrentConsumptionAmount() != null ? mat.getCurrentConsumptionAmount() : 0.0;
                previousTotalConsume = previousTotalConsume + currentConsump;
                price = price + currentConsumptionAmount;
            }
            // 本期消耗量
            mater.setCurrentConsump(getNum(quantity - previousTotalConsume - mater.getCurrentSurplus()));

            // 本期消耗金额 (含税金额(含税单价*采购数量) - 上期累计消金额 - 本期剩余金额(含税单价*本期剩余量))
            // 本期消耗金额 = 含税单价 * 消耗数量

            // 含税金额(含税单价*采购数量)
            double amountIncludingTax = quantity * mater.getUnitPriceTax();
            // 上期累计消金额
            // 本期剩余金额(含税单价*本期剩余量)
            double currentRemainPrice = mater.getUnitPriceTax() * mater.getCurrentSurplus();

            mater.setCurrentConsumptionAmount(getNum(mater.getCurrentConsump() * mater.getUnitPriceTax()));
//            mater.setCurrentConsumptionAmount(getNum(amountIncludingTax - price - currentRemainPrice));
        }


        return toAjax(manageService.updateMater(mater));
    }

    /**
     * 首页面 -> 批量删除
     */
    @PostMapping("/removeMater")
    @ResponseBody
    public AjaxResult removeMater(String ids) {
        try {
            return toAjax(manageService.deleteMaterialById(ids));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    @PostMapping("/listChildMater")
    @ResponseBody
    public TableDataInfo listChildMater(MaterDay materDay) {
        startPage();
        // 获取当前登录人对应的项目权限
        List<MaterDay> materdays = manageService.queryMaterDayList(materDay);
        return getDataTable(materdays);
    }

    @GetMapping("/addViewChildMater")
    public String addViewChildMater(ModelMap mmp, String materialId) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("materialId", materialId);
        return prefix + "/childMaterAdd";
    }

    @GetMapping("/editViewChildMater")
    public String editViewChildMater(ModelMap mmp, String id) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("materialId", id);
        MaterDay materDay = new MaterDay();
        materDay.setId(Integer.valueOf(id));
        List<MaterDay> materDays = manageService.queryMaterDayList(materDay);
        mmp.put("materDay", materDays.get(0));
        return prefix + "/childMaterEdit";
    }

    /**
     * 新增页面 -> 保存
     */
    @PostMapping("/addChildMater")
    @ResponseBody
    public AjaxResult addChildMater(MaterDay materDay) {
        // Step1 校验日期的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkPurchaseDateUnique(materDay))) {
            return error("存在重复日期!");
        }
        // Step2 新增物料子表
        manageService.insertMaterialDay(materDay);

        // Step2 更新物料主表 -> 采购数量
        Mater mater = updateMaterPurchase(materDay);
        return toAjax(manageService.updateMater(mater));
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/editChildMater")
    @ResponseBody
    public AjaxResult editChildMater(MaterDay materDay) {
        // Step1 校验日期的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkPurchaseDateUniqueEdit(materDay))) {
            return error("存在重复日期!");
        }

        // Step2 更新物料子表
        manageService.updateMaterialDay(materDay);

        // Step2 更新物料主表 -> 采购数量
        Mater mater = updateMaterPurchase(materDay);
        return toAjax(manageService.updateMater(mater));
    }

    /**
     * 首页面 -> 批量删除
     */
    @PostMapping("/removeMaterialDay")
    @ResponseBody
    public AjaxResult deleteMaterialDayById(String ids, String materialId) {
        try {
            manageService.deleteMaterialDayById(ids);
            MaterDay materDay = new MaterDay();
            materDay.setMaterialId(Integer.valueOf(materialId));
            Mater mater = updateMaterPurchase(materDay);
            return toAjax(manageService.updateMater(mater));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/exportChildMater")
    @ResponseBody
    public AjaxResult exportChildMater(MaterDay materDay) {
        List<MaterDay> materdays = manageService.queryMaterDayList(materDay);
        ExcelUtil<MaterDay> util = new ExcelUtil<MaterDay>(MaterDay.class);
        return util.exportExcel(materdays, "材料费用日表");
    }


    /**
     * 首页面 -> 下载模板
     */
    @GetMapping("/importTemplateMater")
    @ResponseBody
    public AjaxResult importTemplateMater() {
        ExcelUtil<MaterDay> util = new ExcelUtil<MaterDay>(MaterDay.class);
        return util.importTemplateExcel("材料每日数据");
    }

    @RequestMapping("/importDataMater")
    @ResponseBody
    public AjaxResult importDataMater(MultipartFile file, String materId) throws Exception {
        ExcelUtil<MaterDay> util = new ExcelUtil<MaterDay>(MaterDay.class);
        List<MaterDay> materDayList = util.importExcel(file.getInputStream());
        String message = manageService.importMaterDay(materDayList, materId);
        return AjaxResult.success(message);
    }

    /**
     * 子表变动 -> 更新主表采购数量
     *
     * @param materDay
     * @return
     */
    private Mater updateMaterPurchase(MaterDay materDay) {
        List<MaterDay> materDays = manageService.queryMaterDayListBypId(materDay);
        double sum = 0;
        if (StringUtils.isNotEmpty(materDays)) {
            for (MaterDay materObj : materDays) {
                double purchaseQuantity = Double.valueOf(materObj.getPurchaseQuantity());
                sum = sum + purchaseQuantity;
            }
        }
        Mater mater = new Mater();
        mater.setMaterialId(materDay.getMaterialId());
        mater.setPurchaseQuantity(sum);
        return mater;
    }

    /**
     * @param args
     */
    public Double getNum(Double dou) {
        DecimalFormat df = new DecimalFormat("######0");
        return Double.valueOf(df.format(dou));
    }

    // 机械费用 -> 月表
    @PostMapping("/listMachinery")
    @ResponseBody
    public TableDataInfo listMachinery(Machinery machinery) {
        startPage();
        machinery.setProgramName(machinery.getProgramName().trim().replaceAll(",", ""));
        machinery.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Machinery> machinerys = manageService.queryMachinerylist(machinery);

        // 含税金额
        if (StringUtils.isNotEmpty(machinerys)) {
            for (Machinery machineryObj : machinerys) {
                List<Machinery> machineryList = manageService.queryMachineryForCount(machineryObj);
//                double lastMonthSurplusDiesel = machineryObj.getLastMonthSurplusDiesel();
//                double currentMonthSurplusDiesel = machineryObj.getCurrentMonthSurplusDiesel();

                double monthEndFuelConsumption = machineryObj.getMonthEndFuelConsumption();
                // 采购数量
                if (StringUtils.isNotEmpty(machineryList)) {
                    double workTimeTotal = 0;
                    double fuelMonthConsumpTotal = 0;
                    double machineryUsageFee = 0;
                    double dieselPrice = 0;
                    double deductionExpense = 0;
                    for (Machinery machiner : machineryList) {
                        // 当月的租赁单价
                        double rentalUnitPrice = machiner.getRentalUnitPrice() != 0 ? machiner.getRentalUnitPrice() : 0.0;
                        // 柴油单价
                        double dieselUnitPrice = machiner.getDieselUnitPrice() != 0 ? machiner.getDieselUnitPrice() : 0.0;

                        // 累计工作时间、本月加油量
                        double workTimeMonth = machiner.getWorkTime() != 0 ? machiner.getWorkTime() : 0.0;
                        double fuelMonthConsumpMonth = machiner.getFuelMonthConsump() != 0 ? machiner.getFuelMonthConsump() : 0.0;

                        // 当月机械使用费 (租赁单价*工作时间)
                        machineryUsageFee = getNum(rentalUnitPrice * workTimeMonth);
                        dieselPrice = getNum(dieselUnitPrice * fuelMonthConsumpMonth);

                        // 本月平均油耗(本月加油量+月末加油量)/工作时间
                        if (workTimeMonth != 0) {
                            machineryObj.setMonthAverageFuel(getNum((monthEndFuelConsumption + fuelMonthConsumpMonth) / workTimeMonth));
                        } else {
                            machineryObj.setMonthAverageFuel(0);
                        }

                        // 需扣除费用
                        deductionExpense = machiner.getDeductionExpense();

                        workTimeTotal = workTimeTotal + workTimeMonth;    // 累计工作时间
                        fuelMonthConsumpTotal = fuelMonthConsumpTotal + fuelMonthConsumpMonth;  // 累计加油量
                    }
                    machineryObj.setMachineryUsageFee(machineryUsageFee); // 机械使用费
                    machineryObj.setDieselPrice(dieselPrice);   // 油费
                    machineryObj.setTotalMonthPrice(machineryUsageFee + dieselPrice - deductionExpense);   // 本月费用合计

                    // 更新本月费用合计
                    manageService.updateMachineryTotalPrice(machineryObj);

                    machineryObj.setWorkTime(workTimeTotal);           // 工作时间
                    machineryObj.setFuelMonthConsump(fuelMonthConsumpTotal);    // 本月加油量
                } else {
                    machineryObj.setWorkTime(0.0);
                    machineryObj.setFuelMonthConsump(0.0);
                }
            }
        }

        return getDataTable(machinerys);
    }

    /**
     * 新增页面
     */
    @GetMapping("/addMachineryView")
    public String addMachineryView(ModelMap mmp, String programName, String companyId, String programId) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("rentalNames", sysDictDataService.selectDictDataByType("rental_name"));
        mmp.put("companyId", companyId);
        mmp.put("programId", programId);
        mmp.put("programName", programName);
        return prefix + "/machineryAdd";
    }

    /**
     * 新增页面 -> 保存
     */
    @PostMapping("/saveMachinery")
    @ResponseBody
    public AjaxResult saveMachinery(Machinery machinery) {
        // Step1 校验同一个项目下,月份、出租单位、机械编号的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMachineryUniqueAdd(machinery))) {
            return error("当前月存在重复机械！");
        }
        return toAjax(manageService.insertMachinery(machinery));
    }

    /**
     * 编辑页面
     */
    @GetMapping("/editMachineryView")
    public String editMachineryView(ModelMap mmp, String machineryId) {
        Map<String, Object> map = new HashMap<>();
        map.put("machineryId", machineryId);
        Machinery machinery = new Machinery();
        machinery.setMachineryId(Integer.valueOf(machineryId));
        // 机械费用管理信息
        List<Machinery> machinerys = manageService.queryMachinerylist(machinery);

        SysDictSon sysDictSon = new SysDictSon();
        sysDictSon.setId(machinerys.get(0).getMachineryNumberId());
        sysDictSon.setDictCode(machinerys.get(0).getRentalId());
        List<SysDictSon> sysDictSons = sysDictDataService.selectDictSonById(sysDictSon);
        List<SysDictSon> machineryNumbers = sysDictDataService.selectDictSonByCode(sysDictSon);
        mmp.put("machineryNumberId", sysDictSons.get(0).getId());
        mmp.put("machineryNumbers", machineryNumbers);
        mmp.put("rentalNames", sysDictDataService.selectDictDataByType("rental_name"));
        mmp.put("machinery", machinerys.get(0));
        return prefix + "/machineryEdit";
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/editMachinery")
    @ResponseBody
    public AjaxResult editMachinery(Machinery machinery) {
        // Step1 校验同一个项目下,月份、出租单位、机械编号的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMachineryUniqueEdit(machinery))) {
            return error("存在重复月份或物料！");
        }
        return toAjax(manageService.updateMachinery(machinery));
    }

    @PostMapping("/removeMachinery")
    @ResponseBody
    public AjaxResult removeMachinery(String ids) {
        try {
            return toAjax(manageService.deleteMachineryById(ids));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/exportMachinery")
    @ResponseBody
    public AjaxResult exportMachinery(Machinery machinery) {

        machinery.setProgramName(machinery.getProgramName().trim().replaceAll(",", ""));
        machinery.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Machinery> machinerys = manageService.queryMachinerylist(machinery);

        // 含税金额
        if (StringUtils.isNotEmpty(machinerys)) {
            for (Machinery machineryObj : machinerys) {
                List<Machinery> machineryList = manageService.queryMachineryForCount(machineryObj);

                double monthEndFuelConsumption = machineryObj.getMonthEndFuelConsumption();
                // 采购数量
                if (StringUtils.isNotEmpty(machineryList)) {
                    double workTimeTotal = 0;
                    double fuelMonthConsumpTotal = 0;
                    double machineryUsageFee = 0;
                    double dieselPrice = 0;
                    double deductionExpense = 0;
                    for (Machinery machiner : machineryList) {
                        // 当月的租赁单价
                        double rentalUnitPrice = machiner.getRentalUnitPrice() != 0 ? machiner.getRentalUnitPrice() : 0.0;
                        // 柴油单价
                        double dieselUnitPrice = machiner.getDieselUnitPrice() != 0 ? machiner.getDieselUnitPrice() : 0.0;

                        // 累计工作时间、本月加油量
                        double workTimeMonth = machiner.getWorkTime() != 0 ? machiner.getWorkTime() : 0.0;
                        double fuelMonthConsumpMonth = machiner.getFuelMonthConsump() != 0 ? machiner.getFuelMonthConsump() : 0.0;

                        // 当月机械使用费 (租赁单价*工作时间)
                        machineryUsageFee = getNum(rentalUnitPrice * workTimeMonth);
                        dieselPrice = getNum(dieselUnitPrice * fuelMonthConsumpMonth);

                        // 本月平均油耗
                        if (workTimeMonth != 0) {
                            machineryObj.setMonthAverageFuel(getNum((monthEndFuelConsumption + fuelMonthConsumpMonth) / workTimeMonth));
                        } else {
                            machineryObj.setMonthAverageFuel(0);
                        }
                        // 需扣除费用
                        deductionExpense = machiner.getDeductionExpense();
                        workTimeTotal = workTimeTotal + workTimeMonth;    // 累计工作时间
                        fuelMonthConsumpTotal = fuelMonthConsumpTotal + fuelMonthConsumpMonth;  // 累计加油量
                    }
                    machineryObj.setMachineryUsageFee(machineryUsageFee); // 机械使用费
                    machineryObj.setDieselPrice(dieselPrice);   // 油费
                    machineryObj.setTotalMonthPrice(machineryUsageFee + dieselPrice - deductionExpense);   // 本月费用合计


                    machineryObj.setWorkTime(workTimeTotal);           // 工作时间
                    machineryObj.setFuelMonthConsump(fuelMonthConsumpTotal);    // 本月加油量
                } else {
                    machineryObj.setWorkTime(0.0);
                    machineryObj.setFuelMonthConsump(0.0);
                }
            }
        }
        ExcelUtil<Machinery> util = new ExcelUtil<Machinery>(Machinery.class);
        return util.exportExcel(machinerys, "包时机械费用");
    }

    // 机械费用 -> 日表
    @PostMapping("/listChildMachinery")
    @ResponseBody
    public TableDataInfo listChildMachinery(MachineryDay machineryDay) {
        startPage();
        // 获取当前登录人对应的项目权限
        List<MachineryDay> machineryDays = manageService.queryMachineryDayList(machineryDay);
        return getDataTable(machineryDays);
    }

    @GetMapping("/addViewChildMachinery")
    public String addViewChildMachinery(ModelMap mmp, String machineryId) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("machineryId", machineryId);
        return prefix + "/childMachineryAdd";
    }

    @PostMapping("/addChildMachinery")
    @ResponseBody
    public AjaxResult addChildMachinery(MachineryDay machineryDay) {
        // Step1 校验日期的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkDateUnique(machineryDay))) {
            return error("存在重复日期!");
        }
        // Step2 新增机械子表
        manageService.insertMachineryDay(machineryDay);

        // Step2 更新物料主表 -> 采购数量
        Machinery machinery = manageService.updateMachineryPurchase(machineryDay);
        return toAjax(manageService.updateMachinery(machinery));
    }

    /**
     * 子表变动 -> 更新主表采购数量
     *
     * @param materDay
     * @return
     */
    private Machinery updateMachineryPurchaseMonth(MachineryDay machineryDay) {
        List<MachineryDay> machineryDays = manageService.queryMachineryDayListBypIdMonth(machineryDay);
        double workTimeTotal = 0;
        double fuelConsumpTotal = 0;
        if (StringUtils.isNotEmpty(machineryDays)) {
            for (MachineryDay machineryObj : machineryDays) {
                double workTimeDay = Double.valueOf(machineryObj.getWorkTimeDay());
                if (workTimeDay != 0) {
                    workTimeTotal = workTimeTotal + 1;
                }
                double fuelDayConsump = Double.valueOf(machineryObj.getFuelDayConsump());
                fuelConsumpTotal = fuelConsumpTotal + fuelDayConsump;
            }
        }
        Machinery machinery = new Machinery();
        machinery.setMachineryId(machineryDay.getPId());
        machinery.setWorkTime(workTimeTotal);
        machinery.setFuelMonthConsump(fuelConsumpTotal);
        return machinery;
    }

    /**
     * 编辑页面
     */
    @GetMapping("/editViewChildMachinery")
    public String editViewChildMachinery(ModelMap mmp, String pId, String id) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("pId", pId);
        MachineryDay machineryDay = new MachineryDay();
        machineryDay.setId(Integer.valueOf(id));
        List<MachineryDay> machineryDays = manageService.queryMachineryDayList(machineryDay);
        mmp.put("machineryDay", machineryDays.get(0));
        return prefix + "/childMachineryEdit";
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/editChildMachinery")
    @ResponseBody
    public AjaxResult editChildMachinery(MachineryDay machineryDay) {
        // Step1 校验日期的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkDateUniqueEdit(machineryDay))) {
            return error("存在重复日期!");
        }

        // Step2 更新物料子表
        manageService.updateMachineryDay(machineryDay);

        // Step3 更新物料主表 -> 采购数量
        Machinery machinery = manageService.updateMachineryPurchase(machineryDay);
        return toAjax(manageService.updateMachinery(machinery));
    }

    /**
     * 首页面 -> 批量删除
     */
    @PostMapping("/removeMachineryDay")
    @ResponseBody
    public AjaxResult deleteMachineryDayById(String ids, String pId) {
        try {
            manageService.deleteMachineryDayById(ids);
            MachineryDay machineryDay = new MachineryDay();
            machineryDay.setPId(Integer.valueOf(pId));
            Machinery machinery = manageService.updateMachineryPurchase(machineryDay);
            return toAjax(manageService.updateMachinery(machinery));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/exportChildMachinery")
    @ResponseBody
    public AjaxResult exportChildMachinery(MachineryDay machineryDay) {
        List<MachineryDay> machineryDays = manageService.queryMachineryDayList(machineryDay);
        ExcelUtil<MachineryDay> util = new ExcelUtil<MachineryDay>(MachineryDay.class);
        return util.exportExcel(machineryDays, "包时机械日费表");
    }

    /**
     * 首页面 -> 下载模板
     */
    @GetMapping("/importTemplate")
    @ResponseBody
    public AjaxResult importTemplate() {
        ExcelUtil<MachineryDay> util = new ExcelUtil<MachineryDay>(MachineryDay.class);
        return util.importTemplateExcel("机械每日数据");
    }

    /**
     * 材料月表导入
     *
     * @return
     */
    @GetMapping("/importTemplatesMachinery")
    @ResponseBody
    public AjaxResult importTemplatesMachinery() {
        ExcelUtil<MachineryImport> util = new ExcelUtil<MachineryImport>(MachineryImport.class);
        return util.importTemplateExcel("包时机械每月数据");
    }

    /**
     * 材料月表导入
     *
     * @return
     */
    @GetMapping("/importTemplatesMachineryMonth")
    @ResponseBody
    public AjaxResult importTemplatesMachineryMonth() {
        ExcelUtil<MachineryNewMonth> util = new ExcelUtil<MachineryNewMonth>(MachineryNewMonth.class);
        return util.importTemplateExcel("包月机械每月数据");
    }

    /**
     * 材料月表导入
     *
     * @return
     */
    @GetMapping("/importTemplates")
    @ResponseBody
    public AjaxResult importTemplates() {
        ExcelUtil<MaterImport> util = new ExcelUtil<MaterImport>(MaterImport.class);
        return util.importTemplateExcel("材料每月数据");
    }

    /**
     * 机械 -> 包时 -> 首页导入
     */
    @RequestMapping("/importData")
    @ResponseBody
    public AjaxResult importData(MultipartFile file, String machineryId) throws Exception {
        ExcelUtil<MachineryDay> util = new ExcelUtil<MachineryDay>(MachineryDay.class);
        List<MachineryDay> machineryDayList = util.importExcel(file.getInputStream());
        String message = manageService.importMachineryDay(machineryDayList, machineryId);
        return AjaxResult.success(message);
    }

    /**
     * 机械 -> 包时 -> 首页导入
     */
    @RequestMapping("/importMater")
    @ResponseBody
    public AjaxResult importMater(MultipartFile file, MaterImport materImport) throws Exception {
        ExcelUtil<MaterImport> util = new ExcelUtil<MaterImport>(MaterImport.class);
        List<MaterImport> list = util.importExcel(file.getInputStream());
        String message = manageService.importMaters(list, materImport);
        return AjaxResult.success(message);
    }

    /**
     * 机械 -> 包时 -> 首页导入
     */
    @RequestMapping("/importMachinery")
    @ResponseBody
    public AjaxResult importMachinery(MultipartFile file, MachineryImport machineryImport) throws Exception {
        ExcelUtil<MachineryImport> util = new ExcelUtil<MachineryImport>(MachineryImport.class);
        List<MachineryImport> list = util.importExcel(file.getInputStream());
        String message = manageService.importMachinery(list, machineryImport);
        return AjaxResult.success(message);
    }

    /**
     * 机械 -> 包时 -> 首页导入
     */
    @RequestMapping("/importMachineryMonth")
    @ResponseBody
    public AjaxResult importMachineryMonth(MultipartFile file, MachineryNewMonth machineryNewMonth) throws Exception {
        ExcelUtil<MachineryNewMonth> util = new ExcelUtil<MachineryNewMonth>(MachineryNewMonth.class);
        List<MachineryNewMonth> list = util.importExcel(file.getInputStream());
        String message = manageService.importMachineryMonth(list, machineryNewMonth);
        return AjaxResult.success(message);
    }


    // 机械费用 包月 -> 月表
    @PostMapping("/listMachineryMonth")
    @ResponseBody
    public TableDataInfo queryMachinerylistMonth(Machinery machinery) {
        startPage();
        machinery.setProgramName(machinery.getProgramName().trim().replaceAll(",", ""));
        machinery.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Machinery> machinerys = manageService.queryMachinerylistMonth(machinery);

        // 含税金额
        if (StringUtils.isNotEmpty(machinerys)) {
            for (Machinery machineryObj : machinerys) {
                List<Machinery> machineryList = manageService.queryMachineryForCountMonth(machineryObj);
//                double lastMonthSurplusDiesel = machineryObj.getLastMonthSurplusDiesel();
//                double currentMonthSurplusDiesel = machineryObj.getCurrentMonthSurplusDiesel();

                double monthEndFuelConsumption = machineryObj.getMonthEndFuelConsumption();
                // 采购数量
                if (StringUtils.isNotEmpty(machineryList)) {
                    double workTimeTotal = 0;
                    double fuelMonthConsumpTotal = 0;
                    double machineryUsageFee = 0;
                    double dieselPrice = 0;
                    for (Machinery machiner : machineryList) {
                        // 当月的租赁单价
                        double rentalUnitPrice = machiner.getRentalUnitPrice() != 0 ? machiner.getRentalUnitPrice() : 0.0;
                        double deductionExpense = machiner.getDeductionExpense() != 0 ? machiner.getDeductionExpense() : 0.0;
                        // 柴油单价
                        double dieselUnitPrice = machiner.getDieselUnitPrice() != 0 ? machiner.getDieselUnitPrice() : 0.0;

                        // 累计工作时间、本月加油量
                        double workTimeMonth = machiner.getWorkTime() != 0 ? machiner.getWorkTime() : 0.0;
                        double fuelMonthConsumpMonth = machiner.getFuelMonthConsump() != 0 ? machiner.getFuelMonthConsump() : 0.0;

                        // 当月机械使用费 (租赁单价  - 需扣除费用)
                        machineryUsageFee = getNum(rentalUnitPrice - deductionExpense);
                        dieselPrice = getNum(dieselUnitPrice * fuelMonthConsumpMonth);

                        // 本月平均油耗
                        if (workTimeMonth != 0) {
                            machineryObj.setMonthAverageFuel(getNum((monthEndFuelConsumption + fuelMonthConsumpMonth) / workTimeMonth));
                        } else {
                            machineryObj.setMonthAverageFuel(0);
                        }

                        workTimeTotal = workTimeTotal + workTimeMonth;    // 累计工作时间
                        fuelMonthConsumpTotal = fuelMonthConsumpTotal + fuelMonthConsumpMonth;  // 累计加油量

                        machineryObj.setMachineryUsageFee(machineryUsageFee); // 机械使用费
                        machineryObj.setDieselPrice(dieselPrice);   // 油费
                        machineryObj.setTotalMonthPrice(machineryUsageFee + dieselPrice);   // 本月费用合计

                        // 更新本月费用合计
                        manageService.updateMachineryMonthTotalPrice(machineryObj);

                        machineryObj.setWorkTime(workTimeTotal);           // 工作时间
                        machineryObj.setFuelMonthConsump(fuelMonthConsumpTotal);    // 本月加油量
                    }
                } else {
                    machineryObj.setWorkTime(0.0);
                    machineryObj.setFuelMonthConsump(0.0);
                }
            }
        }
        return getDataTable(machinerys);
    }

    /**
     * 新增页面
     */
    @GetMapping("/addMachineryViewMonth")
    public String addMachineryViewMonth(ModelMap mmp, String programName, String companyId, String programId) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("rentalNames", sysDictDataService.selectDictDataByType("rental_name"));
        mmp.put("companyId", companyId);
        mmp.put("programId", programId);
        mmp.put("programName", programName);
        return prefix + "/machineryAddMonth";
    }

    /**
     * 新增页面 -> 保存
     */
    @PostMapping("/saveMachineryMonth")
    @ResponseBody
    public AjaxResult saveMachineryMonth(Machinery machinery) {
        // Step1 校验同一个项目下,月份、出租单位、机械编号的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMachineryUniqueAddMonth(machinery))) {
            return error("当前月存在重复机械！");
        }
        return toAjax(manageService.insertMachineryMonth(machinery));
    }

    /**
     * 编辑页面
     */
    @GetMapping("/editMachineryViewMonth")
    public String editMachineryViewMonth(ModelMap mmp, String machineryId) {
        Map<String, Object> map = new HashMap<>();
        map.put("machineryId", machineryId);
        Machinery machinery = new Machinery();
        machinery.setMachineryId(Integer.valueOf(machineryId));
        // 机械费用管理信息
        List<Machinery> machinerys = manageService.queryMachinerylistMonth(machinery);

        SysDictSon sysDictSon = new SysDictSon();
        sysDictSon.setId(machinerys.get(0).getMachineryNumberId());
        sysDictSon.setDictCode(machinerys.get(0).getRentalId());
        List<SysDictSon> sysDictSons = sysDictDataService.selectDictSonById(sysDictSon);
        List<SysDictSon> machineryNumbers = sysDictDataService.selectDictSonByCode(sysDictSon);
        mmp.put("machineryNumberId", sysDictSons.get(0).getId());
        mmp.put("machineryNumbers", machineryNumbers);
        mmp.put("rentalNames", sysDictDataService.selectDictDataByType("rental_name"));
        mmp.put("machinery", machinerys.get(0));
        return prefix + "/machineryEditMonth";
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/editMachineryMonth")
    @ResponseBody
    public AjaxResult editMachineryMonth(Machinery machinery) {
        // Step1 校验同一个项目下,月份、出租单位、机械编号的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkMachineryUniqueEditMonth(machinery))) {
            return error("存在重复月份或物料！");
        }
        return toAjax(manageService.updateMachineryMonth(machinery));
    }

    @PostMapping("/removeMachineryMonth")
    @ResponseBody
    public AjaxResult removeMachineryMonth(String ids) {
        try {
            return toAjax(manageService.deleteMachineryByIdMonth(ids));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/exportMachineryMonth")
    @ResponseBody
    public AjaxResult exportMachineryMonth(Machinery machinery) {

        machinery.setProgramName(machinery.getProgramName().trim().replaceAll(",", ""));
        machinery.setUserId(ShiroUtils.getSysUser().getUserId());
        List<Machinery> machinerys = manageService.queryMachinerylistMonth(machinery);

        // 含税金额
        if (StringUtils.isNotEmpty(machinerys)) {
            for (Machinery machineryObj : machinerys) {
                List<Machinery> machineryList = manageService.queryMachineryForCountMonth(machineryObj);

                double monthEndFuelConsumption = machineryObj.getMonthEndFuelConsumption();

                // 采购数量
                if (StringUtils.isNotEmpty(machineryList)) {
                    double workTimeTotal = 0;
                    double fuelMonthConsumpTotal = 0;
                    double machineryUsageFee = 0;
                    double dieselPrice = 0;
                    for (Machinery machiner : machineryList) {
                        // 当月的租赁单价
                        double rentalUnitPrice = machiner.getRentalUnitPrice() != 0 ? machiner.getRentalUnitPrice() : 0.0;
                        double deductionExpense = machiner.getDeductionExpense() != 0 ? machiner.getDeductionExpense() : 0.0;
                        // 柴油单价
                        double dieselUnitPrice = machiner.getDieselUnitPrice() != 0 ? machiner.getDieselUnitPrice() : 0.0;

                        // 累计工作时间、本月加油量
                        double workTimeMonth = machiner.getWorkTime() != 0 ? machiner.getWorkTime() : 0.0;
                        double fuelMonthConsumpMonth = machiner.getFuelMonthConsump() != 0 ? machiner.getFuelMonthConsump() : 0.0;

                        // 当月机械使用费 (租赁单价*工作时间)
                        machineryUsageFee = getNum(rentalUnitPrice - deductionExpense);
                        dieselPrice = getNum(dieselUnitPrice * fuelMonthConsumpMonth);

                        // 本月平均油耗
                        if (workTimeMonth != 0) {
                            machineryObj.setMonthAverageFuel(getNum((monthEndFuelConsumption + fuelMonthConsumpMonth) / workTimeMonth));
                        } else {
                            machineryObj.setMonthAverageFuel(0);
                        }
                        workTimeTotal = workTimeTotal + workTimeMonth;    // 累计工作时间
                        fuelMonthConsumpTotal = fuelMonthConsumpTotal + fuelMonthConsumpMonth;  // 累计加油量
                    }
                    machineryObj.setMachineryUsageFee(machineryUsageFee); // 机械使用费
                    machineryObj.setDieselPrice(dieselPrice);   // 油费
                    machineryObj.setTotalMonthPrice(machineryUsageFee + dieselPrice);   // 本月费用合计


                    machineryObj.setWorkTime(workTimeTotal);           // 工作时间
                    machineryObj.setFuelMonthConsump(fuelMonthConsumpTotal);    // 本月加油量
                } else {
                    machineryObj.setWorkTime(0.0);
                    machineryObj.setFuelMonthConsump(0.0);
                }
            }
        }

        List<MachineryNew> machineryNewList = new ArrayList<MachineryNew>();
        for (Machinery machineryObj : machinerys) {
            MachineryNew machineryNew = new MachineryNew();
            machineryNew.setMachineryId(machineryObj.getMachineryId());
            machineryNew.setCompanyId(machineryObj.getCompanyId());
            machineryNew.setCompanyName(machineryObj.getCompanyName());
            machineryNew.setProgramId(machineryObj.getProgramId());
            machineryNew.setProgramName(machineryObj.getProgramName());
            machineryNew.setRentalId(machineryObj.getRentalId());
            machineryNew.setRentalIdName(machineryObj.getRentalIdName());
            machineryNew.setTaxRate(machineryObj.getTaxRate());
            machineryNew.setMachineryNumberId(machineryObj.getMachineryNumberId());
            machineryNew.setMachineryNumberIdName(machineryObj.getMachineryNumberIdName());
            machineryNew.setEntryTime(machineryObj.getEntryTime());
            machineryNew.setRentalType(machineryObj.getRentalType());
            machineryNew.setActualMonth(machineryObj.getActualMonth());
            machineryNew.setRentalUnitPriceMonth(machineryObj.getRentalUnitPrice());
            machineryNew.setWorkTime(machineryObj.getWorkTime());
            machineryNew.setDeductionExpense(machineryObj.getDeductionExpense());
            machineryNew.setMachineryUsageFee(machineryObj.getMachineryUsageFee());
            machineryNew.setFuelMonthConsump(machineryObj.getFuelMonthConsump());
            machineryNew.setDieselUnitPrice(machineryObj.getDieselUnitPrice());
            machineryNew.setDieselPrice(machineryObj.getDieselPrice());
            machineryNew.setTotalMonthPrice(machineryObj.getTotalMonthPrice());
            machineryNew.setMonthEndFuelConsumption(machineryObj.getMonthEndFuelConsumption());
            machineryNew.setMonthAverageFuel(machineryObj.getMonthAverageFuel());
            machineryNew.setExitTime(machineryObj.getExitTime());
            machineryNew.setRemark(machineryObj.getRemark());
            machineryNewList.add(machineryNew);
        }
        ExcelUtil<MachineryNew> util = new ExcelUtil<MachineryNew>(MachineryNew.class);
        return util.exportExcel(machineryNewList, "包月机械费用");
    }


    // 机械费用 -> 日表
    @PostMapping("/listChildMachineryMonth")
    @ResponseBody
    public TableDataInfo listChildMachineryMonth(MachineryDay machineryDay) {
        startPage();
        // 获取当前登录人对应的项目权限
        List<MachineryDay> machineryDays = manageService.queryMachineryDayListMonth(machineryDay);
        return getDataTable(machineryDays);
    }

    @GetMapping("/addViewChildMachineryMonth")
    public String addViewChildMachineryMonth(ModelMap mmp, String machineryId) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("machineryId", machineryId);
        return prefix + "/childMachineryAddMonth";
    }

    @PostMapping("/addChildMachineryMonth")
    @ResponseBody
    public AjaxResult addChildMachineryMonth(MachineryDay machineryDay) {
        // Step1 校验日期的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkDateUniqueMonth(machineryDay))) {
            return error("存在重复日期!");
        }
        // Step2 新增机械子表
        manageService.insertMachineryDayMonth(machineryDay);

        // Step2 更新物料主表 -> 采购数量
        Machinery machinery = updateMachineryPurchaseMonth(machineryDay);
        return toAjax(manageService.updateMachineryMonth(machinery));
    }

    /**
     * 编辑页面
     */
    @GetMapping("/editViewChildMachineryMonth")
    public String editViewChildMachineryMonth(ModelMap mmp, String pId, String id) {
        Map<String, Object> map = new HashMap<>();
        mmp.put("pId", pId);
        MachineryDay machineryDay = new MachineryDay();
        machineryDay.setId(Integer.valueOf(id));
        List<MachineryDay> machineryDays = manageService.queryMachineryDayListMonth(machineryDay);
        mmp.put("machineryDay", machineryDays.get(0));
        return prefix + "/childMachineryEditMonth";
    }

    /**
     * 更新页面 -> 编辑
     */
    @PostMapping("/editChildMachineryMonth")
    @ResponseBody
    public AjaxResult editChildMachineryMonth(MachineryDay machineryDay) {
        // Step1 校验日期的唯一性
        if (MsgConstants.MONTH_NOT_UNIQUE.equals(manageService.checkDateUniqueEditMonth(machineryDay))) {
            return error("存在重复日期!");
        }

        // Step2 更新物料子表
        manageService.updateMachineryDayMonth(machineryDay);

        // Step3 更新物料主表 -> 采购数量
        Machinery machinery = updateMachineryPurchaseMonth(machineryDay);
        return toAjax(manageService.updateMachineryMonth(machinery));
    }

    /**
     * 首页面 -> 批量删除
     */
    @PostMapping("/removeMachineryDayMonth")
    @ResponseBody
    public AjaxResult removeMachineryDayMonth(String ids, String pId) {
        try {
            manageService.deleteMachineryDayByIdMonth(ids);
            MachineryDay machineryDay = new MachineryDay();
            machineryDay.setPId(Integer.valueOf(pId));
            Machinery machinery = updateMachineryPurchaseMonth(machineryDay);
            return toAjax(manageService.updateMachineryMonth(machinery));
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 首页面 -> 导出
     */
    @PostMapping("/exportChildMachineryMonth")
    @ResponseBody
    public AjaxResult exportChildMachineryMonth(MachineryDay machineryDay) {
        List<MachineryDay> machineryDays = manageService.queryMachineryDayListMonth(machineryDay);
        ExcelUtil<MachineryDay> util = new ExcelUtil<MachineryDay>(MachineryDay.class);
        return util.exportExcel(machineryDays, "包月机械日费表");
    }

    /**
     * 机械 -> 包时 -> 首页导入
     */
    @RequestMapping("/importDataMonth")
    @ResponseBody
    public AjaxResult importDataMonth(MultipartFile file, String machineryId) throws Exception {
        ExcelUtil<MachineryDay> util = new ExcelUtil<MachineryDay>(MachineryDay.class);
        List<MachineryDay> machineryDayList = util.importExcel(file.getInputStream());
        String message = manageService.importMachineryDayMonth(machineryDayList, machineryId);
        return AjaxResult.success(message);
    }


}
